package com.goldcn.sys.service;

import com.alibaba.druid.util.StringUtils;
import com.goldcn.common.BaseCode;
import com.goldcn.common.CommonUtils;
import com.goldcn.common.RSAUtils;
import com.goldcn.common.ResultData;
import com.goldcn.common.util.UuidUtils;
import com.goldcn.config.PropertiesConfig;
import com.goldcn.interceptor.CurrentUser;
import com.goldcn.sys.dao.GcnSysUserInfoMapper;
import com.goldcn.sys.dao.GcnSysUserMapper;
import com.goldcn.sys.dao.SysConfigExtMapper;
import com.goldcn.sys.dao.SysConfigMapper;
import com.goldcn.sys.dto.LoginDto;
import com.goldcn.sys.dto.RasKey;
import com.goldcn.sys.model.GcnSysUser;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/9/3.
 */
@Service
public class SysUserLoginService {

    @Autowired
    GcnSysUserMapper gcnSysUserMapper;

    @Autowired
    GcnSysUserInfoMapper gcnSysUserInfoMapper;

    @Autowired
    RedisService redisService;

    @Autowired
    SysConfigMapper sysConfigMapper;

    @Autowired
    PropertiesConfig propertiesConfig;

    @Autowired
    SysConfigExtMapper sysConfigExtMapper;

    @Autowired
    SysConfigService sysConfigService;


    private final static int errorValiCode = 0;
    private final static int errorLogin = 0;


    public Object doLogin(LoginDto loginDto, HttpServletRequest request) {

        String userName = loginDto.getUserName(),
                passWord = loginDto.getPassWord(),
                valiCode = loginDto.getValiCode();
        HttpSession session = request.getSession();
        String sessionCode = (String) session.getAttribute("code");
        System.out.println("login=" + session.getId());
        Map<String, Object> resultMap = new HashMap<String, Object>();
        //当前错误次数
        int errCount = (Integer) (session.getAttribute("errCount") == null ? 0 : session.getAttribute("errCount"));
        if (errCount >= 3) {
            if (Strings.isNullOrEmpty(valiCode) || !StringUtils.equalsIgnoreCase(valiCode, sessionCode)) {
                errCount++;
                session.setAttribute("errCount", errCount);

                resultMap.put("Msg", "验证码错误或超时");
                resultMap.put("errCount", errCount);

                return resultMap;
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("userName", userName);
        map.put("passWord", passWord);
        GcnSysUser sysUser = gcnSysUserMapper.validateUserLogin(map);
        if (sysUser == null) {
            errCount++;
            session.setAttribute("errCount", errCount);

            resultMap.put("Msg", "用户名或密码错误");
            resultMap.put("errCount", errCount);
        } else {
            String userID = sysUser.getUserID();
            int isStop = sysUser.getIsStop();
            List<Map<String, String>> sysRoleList = gcnSysUserMapper.findUserRoles(userID);
            if (sysRoleList == null || sysRoleList.size() == 0) {

                resultMap.put("Msg", "该用户暂未授权");
            } else if (isStop == 1) {

                resultMap.put("Msg", "该用户已停用");
            } else if (isStop == 2) {

                resultMap.put("Msg", "该用户已删除");
            } else {
                String rolesID = "";
                List<String> roles = Lists.newArrayList();
                for (int i = 0; i < sysRoleList.size(); i++) {
                    rolesID += sysRoleList.get(i).get("roleID") + ",";
                    roles.add(sysRoleList.get(i).get("roleID"));
                }
                if (CommonUtils.isNotEmpty(rolesID)) {
                    rolesID = rolesID.substring(0, rolesID.length() - 1);
                }
                //List<Map<String, Object>> forbiddenFuns = sysRoleService.findPermissions(roles, sysUser);


                resultMap.put("rolesID", rolesID);
                resultMap.put("userID", sysUser.getUserID());
                resultMap.put("userName", sysUser.getUserName());
                resultMap.put("chinaName", sysUser.getChinaName());

                //缓存token
                resultMap.put("tokenId", sysUser.getUserID());
                String token = redisService.addOrUpdate(resultMap, loginDto, sysUser.getUserID());
                //缓存拓展信息
                sysConfigService.setRedisConfigExt();
                resultMap.put("token", token);

                session.setAttribute("errCount", 0);
            }
        }

        return resultMap;
    }

    public Object updatePassWord(LoginDto loginDto) {
        Map<String, Object> map = new HashMap<>();
        ResultData resultData = new ResultData();
        map.put("userID", loginDto.getUserID());
        map.put("passWord", loginDto.getOldPassWord());
        GcnSysUser sysUser = gcnSysUserMapper.validateUserLogin(map);
        if (sysUser == null) {
            resultData.setMessage("原密码不正确");
            resultData.setCode(BaseCode.ERROR_CODE);
            return resultData;
        }
        sysUser.setPassWord(loginDto.getPassWord());
        int result = gcnSysUserMapper.updateByPrimaryKeySelective(sysUser);
        resultData.setCode(String.valueOf(result));
        return resultData;
    }


    public Object getRASKey() throws Exception {
        System.out.print("=====rasKey====");
        ResultData<RasKey> result = new ResultData<RasKey>();
        KeyPair keyPair = RSAUtils.generateKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        RasKey rasKey = new RasKey();
        rasKey.setExponent(publicKey.getPublicExponent().toString(16));
        rasKey.setModulus(publicKey.getModulus().toString(16));
        rasKey.setRasId(UuidUtils.uuid());
        redisService.addOrUpdateRAS(rasKey.getRasId(), privateKey);
        result.setCode(BaseCode.SUCCESS_CODE);
        result.setData(rasKey);
        return rasKey;
    }

    public Object loginOut(HttpServletRequest request, String userID, String platform) {
        Object o = redisService.loadKey(userID);
        ResultData<String> result = new ResultData<String>();
        if (o == null || o == "") {
            return result;
        } else {
            Object object = null;
            if (Strings.isNullOrEmpty(platform)) {
                redisService.delete(userID);
                redisService.delete(userID + BaseCode.user_dataPres);
                redisService.delete(userID + BaseCode.user_funPres);
                object = redisService.loadKey(userID);
            } else {
                String token = request.getHeader("token");
                if (CommonUtils.isNotEmpty(token)) {
                    CurrentUser user = getCurrentUser(token);
                    String key = user.getTokenId();
                    redisService.delete(key);
                    object = redisService.loadKey(key);
                }
            }

            if (object == null || object == "") {
                return result;
            } else {
                result.setCode(BaseCode.ERROR_CODE);
                return result;
            }
        }
    }


    private CurrentUser getCurrentUser(String token) {
        String userInfo = token.substring(token.indexOf(46), token.lastIndexOf(46));
        userInfo = org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64.decodeBase64(userInfo.getBytes()));
        JSONObject jsStr = JSONObject.fromObject(userInfo);
        CurrentUser user = new CurrentUser();
        user.setUserID(jsStr.get("userID").toString());
        user.setUserName(jsStr.get("userName").toString());
        user.setChinaName(jsStr.get("chinaName").toString());
        user.setRolesID(jsStr.get("rolesID").toString());
        user.setTokenId(jsStr.get("tokenId") != null ? jsStr.get("tokenId").toString() : "");
        return user;
    }

}
